// 手风琴分组式表单，支持字段、字段值依赖，多表单夸分组联动依赖，字段依赖赋值，显隐,动态增减表单
import React, { useImperativeHandle, Fragment } from 'react'
import { Form, Collapse } from 'antd'
const { Panel } = Collapse

import FormWidgetRender from './FormWidgetRender'
import { uuid, throttle } from '@/common/utils'
import { FormLayout, FormInstance } from 'antd/lib/form/Form'
import { FormLabelAlign, Store } from 'antd/lib/form/interface'
import { ColProps } from 'antd/lib/grid/col'
import { RowProps } from 'antd/lib/grid/row'
import { SizeType } from 'antd/lib/config-provider/SizeContext'

export interface UpdateByWatch{
  name: string
  value: any
  type: 'options' | 'listeners'
}
export type ConditionItem = {
  fieldName: string,
  value: any,
  operator: '===' | '!=='
  connector: '||' | '&&'
}
export interface ListenerItem {
  watch: string[],
  condition: ConditionItem[],
  set: any
}
// enum Method {
//   POST = 'POST', // 提交数据（表单提交+文件上传
//   GET = 'GET', // 获取数据
//   DELETE = 'DELETE', // 删除数据
//   PUT = 'PUT', // 更新数据（所有数据推送到后端）
//   PATCH = 'PATCH', // 更新数据（只将更改的数据推送到后端）
//   CONNECT = 'CONNECT',
//   HEAD = 'HEAD',
// }
type Method = 'POST' | 'GET' | 'DELETE' | 'PUT' | 'PATCH' | 'CONNECT' | 'HEAD'
type WidgetStatus = 'edit' | 'disabled' | 'preview' | 'hidden'
export interface OptionsFetch {
  action: string, // action 为接口链接
  method: Method,
  nameProperty?: string, // nameProperty 配置 name 字段
  valueProperty?: string, // valueProperty 配置 value 字段
  path?: string, // path 为获取选项路径
  watch?: string[] // watch 配置监听字段
  search?: any, // 是否搜索，name 为自定义的对应的入参名
  params?: any, // 显隐 叠加refresh场景下，默认会把选择项 整个对象 放入data里进行合并
  headers?: any,
  jsonp?: boolean
}
export interface SchemaItem {
  key: string | number // 唯一标示
  widget: string // 微件名称
  fieldName: string // 字段名
  value: any // 字段值
  status: WidgetStatus // 表单项字段状态 edit（默认）：编辑,disabled：禁用,preview：预览,hidden：隐藏
  options?: any[] | OptionsFetch // // 下拉框微件时的物料数据
  rules?: any[] // 正则规则
  updateByWatch?: UpdateByWatch // 由于依赖导致更新的依赖字段key
  ui: { // col,formitem 的配置属性
    label?: string | number,
    tooltip?:any // 左边icon上的提示语
    colSpan?:number // 所占列数
    offset?:number // 偏移数
    labelCol?: ColProps // 左边文字所占列数
    wrapperCol?: ColProps // 右边微件实体所在列数
    size?: SizeType // 大小
    valuePropName?: string // checked
  },
  props: { // 微件的配置属性
    placeholder?: string
    size?: SizeType // 大小
  },
  listeners?: ListenerItem[],
  index?:number // 索引
}
export interface SchemaTypeItem {
  key: string | number
  title?: string | number
  index?: number
  size?:SizeType
  row?: RowProps, // 表单全局删格布局的行属性，优先级低于list里的行属性设置
  list: SchemaItem[]
}

interface PropsSchemaForm {
  schemaArr: SchemaTypeItem[],
  cRef: any
  formInitialValues?: Store // 表单初始值
  layout?: FormLayout //
  labelAlign?: FormLabelAlign;
  labelCol?: ColProps;
  wrapperCol?: ColProps;
}
const SchemaFormReader = (props: PropsSchemaForm) => {
  const { schemaArr, cRef, layout = 'horizontal', formInitialValues } = props

  // 通过Form.useForm对表单数据域进行交互。useForm是React Hooks的实现，只能用于函数组件
  const [formInstance]:[FormInstance] = Form.useForm()
  // cRef就是父组件传过来的ref
  useImperativeHandle(cRef, () => ({
    // getForm就是暴露给父组件的方法
    getForm: () => formInstance
  }))

  const onFinish = (values: Object) => {
    console.log(values)
  }

  // 重置要配合着const [form] = Form.useForm()以及form={form}
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  const onReset = () => {
    formInstance.resetFields()
  }

    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    const onValuesChange = (changedValues:any, allValues:any) => {
    // console.log('v', changedValues, allValues)
  }

  return <>
    <Form
      name={uuid(5)}
      layout={layout}
      form={formInstance}
      initialValues={formInitialValues}
      onValuesChange={throttle(onValuesChange, 1500)}
    >
      {
        schemaArr?.length ? (
          layout === 'inline' ? (
            <>
              {schemaArr.map((schema: SchemaTypeItem) => {
                return (
                  <Fragment key={schema?.key || uuid(5)}>
                    <FormWidgetRender
                      formInstance={formInstance}
                      schemas={schema?.list}
                      layout={layout}
                      onFinish={onFinish}
                      row={schema?.row}
                    />
                  </Fragment>
                )
              })}
            </>
          ) : (
        <Collapse
          defaultActiveKey={schemaArr.map((sc: SchemaTypeItem) => sc?.key) as string | number[]}
        >
          {schemaArr.map((schema: SchemaTypeItem) => {
            return (
              <Panel header={schema?.title} key={schema?.key || uuid(5)}>
                <FormWidgetRender
                  formInstance={formInstance}
                  schemas={schema?.list}
                  layout={layout}
                  onFinish={onFinish}
                  row={schema?.row}
                />
              </Panel>
            )
          })}
        </Collapse>)) : null
      }
    </Form>
  </>
}

export default SchemaFormReader
